package org.wz.complex.work.kit.encrypt;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.crypto.asymmetric.RSA;
import org.wz.complex.work.consts.PathConst;

import javax.crypto.Cipher;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.*;

import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public interface RsaKit {

    public String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqK/6XCGOW0KaisDKwywGp7270kIpWUzS9F6evlyJZA7Jvvw4zfbxloR+MOgoWF2VVEoH3qf83lY+vazJ2DLdEje/0Vty4kzouu0X3QkU7zV1+6miTK8IL6VrIzuQGS5TcAJs5PL7m4Uoyd8xxF/aCnxheE3zaLh8sBIUlAykTWnIcsMeTv32T/4YQmjdM8s39BRhDC0Kk73VyoYDdzipAqGOFIeeNSO9QqpxzxKWl5Gk41sEItyhFwHALS+yAgGvSdzru1Cf9ABPUrdONUJx3t5JON7K6dK9RWF/rEwIGpjw68Z9sOcOx+JGGKaa8rzRP4El7xMmtk49qgXzFCtJpQIDAQAB";

    public String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCor/pcIY5bQpqKwMrDLAanvbvSQilZTNL0Xp6+XIlkDsm+/DjN9vGWhH4w6ChYXZVUSgfep/zeVj69rMnYMt0SN7/RW3LiTOi67RfdCRTvNXX7qaJMrwgvpWsjO5AZLlNwAmzk8vubhSjJ3zHEX9oKfGF4TfNouHywEhSUDKRNachywx5O/fZP/hhCaN0zyzf0FGEMLQqTvdXKhgN3OKkCoY4Uh541I71CqnHPEpaXkaTjWwQi3KEXAcAtL7ICAa9J3Ou7UJ/0AE9St041QnHe3kk43srp0r1FYX+sTAgamPDrxn2w5w7H4kYYppryvNE/gSXvEya2Tj2qBfMUK0mlAgMBAAECggEACdozZXepRJ/EfnepsBINdnUgt/RYzWgtBwxSubwWYzNw6Zh6Kd9zN08YPruEhbq7is+DG6hUntjLM9FYfank2xhJ+gydDmYfDrHj26tY32rQMAl1mwR7FitTcVycezgHNArUOOAPPYNewUGpurY9ejDPEZN99L8Xu0HnFUmSvBmqDKqsnFZCk/jl3LzGW4pMvtCrjKe7iKYQZTJYxzAOvwnpb9OzvIfllLC5skakSRLMTpiI93PK5/9utQGwBLMxrxk50RnI2T8uh1EPz6R03CVs6nA1Q8I0QSPtHGEVJpPcIoyf/ZnGR9LRqgEfsUkSNqLUiYwMxtK+9GpZVUd+0QKBgQDKVdLRlMAWdxEU2o0pH7hjP/FYWlxK4BiG7ubkaS/gKNQnvB0RRMWMnAM3honQ/j644ehOVto1dBFPn79OyOnRiCgF6lcFDz1r2aDtH2mahf0yIpCDIxy5rOru9gfNuEnqYUCXcwudbCKqhNhxqDifqqNsh1wTI5wYMMGuuObb8QKBgQDVbYfl7qJVeUn802AaUR/evqSF0nNjbpXn7cevi/r6b5YXdg0uifc4hTFXrVEKPKOruW3KUC4z8H9U86wTiwHNuCYZCpGTmgENResMleM9qrAYr0TR60vkLB9FIkPKlVZihiABR43FBMw7brN6zqMPEwQAX3/yF2Jj3KnbnSOM9QKBgQDGi0Ls309CfCHp2a/M29B+q78y2LBZ1N6cgY9WMRWGm+na9896I4bKPEk30jAoQWPg3eSsArPq4fMes/3w3Fv8fOPxMguj7llyHEK6jCl/NN3ItXwjAnBsjo6WYBw2NRFrCXVtZ7nNBtBZjTQrC0xM+Q+WLpkeOsIwRp+3yL7YsQKBgQCNLh8vYmPP1qOyssBnqDJEzidWvpfFtmlDOm9VGGu1LgtDCbw+hNUcdj7lmKh69RHvjoGpytBFW1lfgLDbXKCczKum9O7HjKAVf6K0eJIRQM+sBISpt9RD40vsF3Zwk8jI86BIOGT3Zu0Sg3AGVJpYZmPHO2UPZ5iWJmnV9GSH4QKBgA6ptVE0DCxmozWiLAn+P3JK2IgzY5GM+Lee6VO423d0QQ6coeooTT1K2ATlM1wWX6ONdhKGAo7zYyx9f6AzdCDZKsYFkj+HK0+181Y0+r1nKpfuI/s7wyD/jBeXrVrLuW2eov+izE5WUpNEk7jMcGCIEdY2fkq/2+g0SM1r93qZ";

    // 生成 RSA 密钥对
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        return keyPairGenerator.generateKeyPair();
    }

    // 将公钥转换为 Base64 编码的字符串
    public static String publicKeyToString(PublicKey publicKey) {
        byte[] keyBytes = publicKey.getEncoded();
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    // 将私钥转换为 Base64 编码的字符串
    public static String privateKeyToString(PrivateKey privateKey) {
        byte[] keyBytes = privateKey.getEncoded();
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    // 将 Base64 编码的字符串转换为公钥
    public static PublicKey stringToPublicKey(String publicKeyString) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(publicKeyString);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    // 将 Base64 编码的字符串转换为私钥
    public static PrivateKey stringToPrivateKey(String privateKeyString) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyString);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    // 使用公钥加密
    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // 使用私钥解密
    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    public static void printKeyPair() {
        try {
            // 生成密钥对
            KeyPair keyPair = generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            // 将密钥转换为字符串
            String publicKeyString = publicKeyToString(publicKey);
            String privateKeyString = privateKeyToString(privateKey);

            System.out.println("公钥字符串: " + publicKeyString);
            System.out.println("私钥字符串: " + privateKeyString);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 加密
    public static String encrypt(String plainText) {
        try {
            // 将字符串转换回密钥
            PublicKey restoredPublicKey = stringToPublicKey(PUBLIC_KEY);
            // 待加密的明文
            // 使用恢复的公钥进行加密
            String encryptedText = encrypt(plainText, restoredPublicKey);
            return encryptedText;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 解密
    public static String decrypt(String encryptedText) {
        try {
            // 使用恢复的私钥进行解密
            PrivateKey restoredPrivateKey = stringToPrivateKey(PRIVATE_KEY);
            String decryptedText = decrypt(encryptedText, restoredPrivateKey);
            return decryptedText;
        }   catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static String decodeFile(String filePath) {
        String content = FileUtil.readUtf8String(filePath);
        content = content.replaceAll("======== start ==========================================================", "")
                .replaceAll("======== end ==========================================================", "")
                .replaceAll("\\s+", "")
                .replaceAll("\n", "");
        return decrypt(content);
    }


}
